package com.financing.wap.service.weixin.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import java.util.Map;

import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import me.chanjar.weixin.mp.bean.subscribe.WxMpSubscribeMessage;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.financing.wap.common.CommonConstantUtil.CommonStatus;
import com.financing.wap.common.ResultMap;
import com.financing.wap.dto.DstUserInfoDTO;
import com.financing.wap.service.IDstUserInfoService;
import com.financing.wap.service.weixin.service.WeixinService;
import com.financing.wap.util.AliyunOssUtil;
import com.financing.wap.util.DateUtil;
import com.financing.wap.util.PropertiesUtils;
import com.financing.wap.util.Sign;
import com.financing.wap.util.StringUtil;
import com.financing.wap.weixin.util.WeixinUtil;

/**
 * @author Binary Wang
 */
public abstract class BaseWeixinServiceImpl implements WeixinService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    public  WxMpService wxMpService;

    //文件到目录
    private static String ossUserCardPath = PropertiesUtils.getValue("ossUserCardPath");

    private static String aliyunOss = "true";
    
 // 从微信服务器下载音频文件地址
 	private static String wx_audio_address ="http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID";


    @Autowired
	private IDstUserInfoService dstUserInfoService;

    public WxMpService getWxMpService() {
        return wxMpService;
    }

    public void setWxMpService(WxMpService wxMpService) {
        this.wxMpService = wxMpService;
    }


    @Override
    public String getAccessToken() throws WxErrorException {
       return  wxMpService.getAccessToken();
    }


    /**
     * 构建微信授权认证URL
     *
     * @param redirectURI 回调地址
     * @param scope
     * @param state
     * @return
     */
    @Override
    public String buildAuthorizationUrl(String redirectURI, String scope, String state) {
        if (!StringUtils.equals(WxConsts.OAuth2Scope.SNSAPI_USERINFO, scope)) {
            scope = WxConsts.OAuth2Scope.SNSAPI_BASE;
        }
        String url = wxMpService.oauth2buildAuthorizationUrl(redirectURI, scope, state);
        if (logger.isDebugEnabled()) {
            logger.debug(url);
        }
        return url;
    }

    /**
     * 一次性订阅消息
     *
     * @param redirectURI 回调地址
     * @param scope
     * @param reserved
     * @return
     */
    @Override
    public String subscribeMsgAuthorizationUrl(String redirectURI, Integer scope, String reserved) {

        String url = wxMpService.getSubscribeMsgService().subscribeMsgAuthorizationUrl(redirectURI, scope, reserved);
        if (logger.isDebugEnabled()) {
            logger.debug(url);
        }
        return url;
    }

    /**
     * 发送 一次性订阅消息
     *
     * @param subscribeMessage 消息对象
     * @return
     */
    @Override
    public boolean sendSubscribeMessage(WxMpSubscribeMessage subscribeMessage) throws WxErrorException {

        boolean flag = wxMpService.getSubscribeMsgService().sendSubscribeMessage(subscribeMessage);
        return flag;
    }

    /**
     * 获得用户基本信息
     *
     * @param code
     * @return
     */
    @Override
    public WxMpUser getUserInfo(String code) {
        WxMpUser wxMpUser = getUserInfo(code, null);
        if (logger.isDebugEnabled()) {
            logger.debug(wxMpUser.toString());
        }
        return wxMpUser;
    }

    /**
     * 获得用户基本信息
     *
     * @param code
     * @param lang
     * @return
     */
    public WxMpUser getUserInfo(String code, String lang) {
        WxMpOAuth2AccessToken wxMpOAuth2AccessToken = oauth2getAccessToken(code);
        WxMpUser wxMpUser = getUserInfo(wxMpOAuth2AccessToken, lang);
        return wxMpUser;
    }

    /**
     * 获得用户基本信息
     *
     * @param token
     * @param lang
     * @return
     */
    @Override
    public WxMpUser getUserInfo(WxMpOAuth2AccessToken token, String lang) {
        WxMpUser wxMpUser = null;
        try {
            wxMpUser = wxMpService.oauth2getUserInfo(token, lang);
            if (logger.isDebugEnabled()) {
                logger.debug(wxMpUser.toString());
            }
        } catch (WxErrorException e) {
            logger.error(e.getMessage(), e);
        }

        return wxMpUser;
    }

    /**
     * 获得access token
     * <p>当用户同意授权后，会回调所设置的url并把authorization code传过来，然后用这个code获得access token，其中也包含用户的openid等信息</p>
     *
     * @param code
     * @return
     */
    @Override
    public WxMpOAuth2AccessToken oauth2getAccessToken(String code) {

        WxMpOAuth2AccessToken wxMpOAuth2AccessToken = null;
        try {
            wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code);
            if (logger.isDebugEnabled()) {
                logger.debug(wxMpOAuth2AccessToken.toString());
            }
        } catch (WxErrorException e) {
            logger.error(e.getMessage(), e);
        }
        return wxMpOAuth2AccessToken;
    }

    /**
     * 刷新access token
     *
     * @param wxMpOAuth2AccessToken
     * @return
     */
    @Override
    public WxMpOAuth2AccessToken refreshAccessToken(WxMpOAuth2AccessToken wxMpOAuth2AccessToken) {
        WxMpOAuth2AccessToken wxMpOAuth2AccessToken1 = null;
        try {
            wxMpOAuth2AccessToken1 = wxMpService.oauth2refreshAccessToken(wxMpOAuth2AccessToken.getRefreshToken());
            if (logger.isDebugEnabled()) {
                logger.debug(wxMpOAuth2AccessToken1.toString());
            }
        } catch (WxErrorException e) {
            logger.error(e.getMessage(), e);
        }
        return wxMpOAuth2AccessToken1;
    }

    /**
     * 验证access token
     *
     * @param wxMpOAuth2AccessToken
     * @return
     */
    @Override
    public boolean validateAccessToken(WxMpOAuth2AccessToken wxMpOAuth2AccessToken) {
        boolean valid = wxMpService.oauth2validateAccessToken(wxMpOAuth2AccessToken);
        return valid;
    }
    /**
     * 保存信息到表-wx_mp_user
     * @param wxMpUser
     * @return
     */
    @Override
    public Boolean saveMpUserToLocal(WxMpUser wxMpUser){

        if(wxMpUser == null ||  StringUtils.isBlank(wxMpUser.getOpenId())){
            return false;
        }

        DstUserInfoDTO insert = new DstUserInfoDTO();
        insert.setUserWechatOpenid(wxMpUser.getOpenId());
        insert.setUpdateDate(new Date());
        insert.setUserName(wxMpUser.getNickname());
        insert.setUserWechatImage(wxMpUser.getHeadImgUrl());
        insert.setUserWechatAddress(wxMpUser.getCity());
        insert.setUserSex(wxMpUser.getSex());
        //BeanUtils.copyProperties(wxMpUser,insert);
        insert.setUpdateDate(new Date());

        DstUserInfoDTO dstUserInfo=new DstUserInfoDTO();
        dstUserInfo.setDeleteTag(CommonStatus.DELETE_TAG_NORMAL);
        dstUserInfo.setUserWechatOpenid(wxMpUser.getOpenId());
        try {
        	List<DstUserInfoDTO> list =  dstUserInfoService.queryList(dstUserInfo);
	        if(list != null && list.size() >0){
	        	insert.setId(list.get(0).getId());
	        	dstUserInfoService.update(insert);
	        }else {
	            insert.setDeleteTag(CommonStatus.DELETE_TAG_NORMAL);
	            insert.setCreateDate(new Date());
				dstUserInfoService.insert(insert);
	        }
        } catch (SQLException e) {
        	logger.error("query dstUserInfo error",e);
		}

        return true;
    }

    /**
     * 获取-wx_mp_user
     * @param openId 公众号id
     * @return DstUserInfoDTO
     */
    @Override
    public DstUserInfoDTO queryWxMpUserByOpenId(String  openId){

        if(StringUtils.isBlank(openId)){
            return null;
        }

        DstUserInfoDTO dstUserInfo=new DstUserInfoDTO();
        dstUserInfo.setDeleteTag(CommonStatus.DELETE_TAG_NORMAL);
        dstUserInfo.setUserWechatOpenid(openId);
		try {
			 List<DstUserInfoDTO>	list = dstUserInfoService.queryList(dstUserInfo);
	        if(list != null && list.size() >0){
	            return list.get(0);
	        }
	           
		} catch (SQLException e) {
			logger.error("query dstUserInfo by openid error",e);
		}
		 return null;
    }

    /**
     * 获取-wx_mp_user
     * @param unionId 开发平台唯一id
     * @return DstUserInfoDTO
     */
    @Override
    public DstUserInfoDTO queryWxMpUserByUnionId(String unionId){

        if(StringUtils.isBlank(unionId)){
            return null;
        }

        DstUserInfoDTO dstUserInfo=new DstUserInfoDTO();
        dstUserInfo.setDeleteTag(CommonStatus.DELETE_TAG_NORMAL);
        dstUserInfo.setUnionId(unionId);
		try {
			 List<DstUserInfoDTO>	list = dstUserInfoService.queryList(dstUserInfo);
	        if(list != null && list.size() >0){
	            return list.get(0);
	        }
		} catch (SQLException e) {
			logger.error("query dstUserInfo by uinionid error",e);
		}
		 return null;
    }

    @Override
    public boolean sendKefuMessage(WxMpKefuMessage message) throws WxErrorException {
      return  wxMpService.getKefuService().sendKefuMessage(message);
    }

    @Override
    public WxMpUser getUserInfoForUserService(String  openId) throws WxErrorException {
        return  wxMpService.getUserService().userInfo(openId);
    }

    @Override
    public ResultMap getjsApiwxconfig(String requestUrl,String appid)
            throws Exception {
        ResultMap remap = new ResultMap();

        if(StringUtil.isNullOrEmptyStr(requestUrl)){
            remap.setStatus(ResultMap.STATUS.ERROR);
            remap.setStatusCode(ResultMap.STATUS_CODE_PARAMETERS_LOSE);
            return remap;
        }
        logger.info("WechatCoreServiceImpl getjsApiwxconfig requestUrl:"
                + requestUrl);
        requestUrl = URLDecoder.decode(requestUrl);
        logger.info("WechatCoreServiceImpl getjsApiwxconfig URLDecoder requestUrl:"
                + requestUrl);
        String ticket = wxMpService.getJsapiTicket();
        logger.info("WechatCoreServiceImpl getjsApiwxconfig ticket:"
                + ticket);
        // 根据 ticket 生成 sign
        Map<String, String> map = Sign.sign(ticket, requestUrl,appid);
        remap.setAttribute("dto", map);
        remap.setStatus(ResultMap.STATUS.SUCCESS);
        remap.setStatusCode(ResultMap.STATUS_CODE_SUCCESS);
        return remap;
    }
    @Override
    public String getFileByMediaId(String docFormat, String audioMediaId)  {
        // 生成本地服务器存放目录
        StringBuffer fileFullPath = new StringBuffer();
        try {
            // 文件分隔符
            String separator = File.separator;
            fileFullPath.append(ossUserCardPath)
                    .append(separator)
                    .append(DateUtil.getDate());
            fileFullPath.append(separator)
                    .append(audioMediaId)
                    .append("_")
                    .append(System.currentTimeMillis())
                    .append(".")
                    .append(docFormat);
    		// 获取当前生效token
    		String tokenString = this.getAccessToken();
    		// 拼接目标UR
    		String requestUrl = wx_audio_address.replace("ACCESS_TOKEN", tokenString).replace(
    				"MEDIA_ID", audioMediaId);
			logger.info("fileUpload.shtml  requestUrl:"+requestUrl);
			URL url = new URL(requestUrl);
			URLConnection con = url.openConnection();
			InputStream is = con.getInputStream();
            AliyunOssUtil.writeFile(is,fileFullPath.toString());
        } catch (Exception e) {
            logger.error("error getFileByMediaId",e);
        }
        return fileFullPath.toString().replaceAll("/disk","");
    }
    
    /***
     * @param scene
     * @return
     * @throws WxErrorException 
     * @throws FileNotFoundException 
     */
    @Override
    public String qrCodePicture(String scene,String path) throws Exception{
    	WxMpQrCodeTicket ticket = wxMpService.getQrcodeService().qrCodeCreateLastTicket(scene);
		String vCodeUrl = WeixinUtil.showqrcode.replace("TICKET", URLEncoder.encode(ticket.getTicket(),"utf-8"));
		logger.info("requestUrl:"+vCodeUrl);
		URL url = new URL(vCodeUrl);
		URLConnection con = url.openConnection();
		InputStream is = con.getInputStream();
    	AliyunOssUtil.writeFile(is,path);
		return path;
    }
    
    
}
